package com.gec.zhs.excutorTask;

import cn.hutool.core.util.StrUtil;
import com.gec.zhs.component.EsSearchComponent;
import com.gec.zhs.component.RedisComponent;
import com.gec.zhs.entity.dto.VideoPlayInfoDto;
import com.gec.zhs.entity.enums.SearchOrderTypeEnum;
import com.gec.zhs.entity.pojo.VideoInfoFilePost;
import com.gec.zhs.service.VideoInfoPostService;
import com.gec.zhs.service.VideoInfoService;
import com.gec.zhs.service.VideoPlayHistoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.concurrent.*;

/**
 * @author zhs
 * @version 1.0
 * @date 2025-02-09
 * @description IOC
 */
@Component
@Slf4j
public class ExecuteQueueTask {

    @Autowired
    private RedisComponent redisComponent;

    @Autowired
    private VideoInfoPostService videoInfoPostService;

    @Autowired
    private VideoInfoService videoInfoService;

    @Autowired
    private EsSearchComponent esSearchComponent;

    @Autowired
    private VideoPlayHistoryService videoPlayHistoryService;


    private final ExecutorService executorService =
            new ThreadPoolExecutor(2,
                    10,
                    60,
                    TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(Integer.MAX_VALUE - 1),
                    new ThreadPoolExecutor.CallerRunsPolicy());

    /**
     * 分片的filePost对象进行转码
     * 使用的ffmpeg来进行转码、分片
     * 效率慢因此使用8线程加速，本机cpu16线程
     */
    @PostConstruct
    public void consumeVideoTransferQueue() {
        executorService.execute(() -> {
            while (true) {
                VideoInfoFilePost videoInfoFilePost = redisComponent.getFileFormQueue();
                try {
                    if (videoInfoFilePost == null) {
                        Thread.sleep(2000);
                        continue;
                    }
                    //文件转码
                    videoInfoPostService.transferVideoFile(videoInfoFilePost);
                } catch (InterruptedException | IOException e) {
                    log.error("获取文件转码失败:" + e);
                }
            }
        });
    }


    /**
     * 延迟更新视频信息
     * 例如播放量、点赞、投币、弹幕、评论等。
     */
    @PostConstruct
    public void consumeVideoInfoQueue() {
        executorService.execute(() -> {
            while (true) {
                VideoPlayInfoDto videoPlayInfoDto = redisComponent.getVideoPlayInfoDtoFromPlayQueue();
                try {
                    if (videoPlayInfoDto == null) {
                        Thread.sleep(2000);
                        continue;
                    }
                    //更新视频播放量信息
                    videoInfoService.addReadCount(videoPlayInfoDto.getVideoId());
                    if(StrUtil.isNotBlank(videoPlayInfoDto.getUserId())){
                        //记录历史
                        videoPlayHistoryService.saveHistory(videoPlayInfoDto.getUserId(), videoPlayInfoDto.getVideoId(), videoPlayInfoDto.getFileIndex());
                    }
                    /**
                     * 按天记录视频播放数量
                     * 定时任务/计数器
                     * 24小时热门
                     */
                    redisComponent.recordVideoPlayCount(videoPlayInfoDto.getVideoId());

                    //更新es播放数量
                    esSearchComponent.updateDocCount(videoPlayInfoDto.getVideoId(), SearchOrderTypeEnum.VIDEO_PLAY.getField(), 1);

                } catch (InterruptedException e) {
                    log.error("线程被中断，更新视频播放量信息失败: ", e);
                } catch (Exception e) {
                    log.error("处理视频播放信息时出现异常: ", e);
                }
            }
        });
    }

}
